package com.cjm.one.common.utils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;

public class OrderIdGenerator {
    
    // 节点ID（0-1023），通过配置或服务发现获取
    private final int nodeId; 
    
    // 最后时间戳（秒级）
    private volatile long lastTimestamp = -1L;
    
    // 序列号（0-4095）
    private final AtomicInteger sequence = new AtomicInteger(0);
    
    // 时间格式
    private static final DateTimeFormatter TIME_FORMAT = 
        DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    
    // 节点ID最大值（10位）
    private static final int MAX_NODE_ID = 1023;
    
    // 序列号最大值（12位）
    private static final int MAX_SEQUENCE = 4095;

    public OrderIdGenerator(int nodeId) {
        if (nodeId < 0 || nodeId > MAX_NODE_ID) {
            throw new IllegalArgumentException("节点ID范围0-" + MAX_NODE_ID);
        }
        this.nodeId = nodeId;
    }

    /**
     * 生成订单ID（格式：时间戳_节点ID_随机序列）
     */
    public String generate() {
        long currentSecond = getCurrentSecond();
        
        // 时间回拨检测
        if (currentSecond < lastTimestamp) {
            throw new IllegalStateException("系统时间回拨异常");
        }

        // 时间戳更新时重置序列号
        if (currentSecond != lastTimestamp) {
            lastTimestamp = currentSecond;
            sequence.set(ThreadLocalRandom.current().nextInt(256)); // 随机初始序列
        }

        // 生成序列号（CAS自旋）
        int seq;
        do {
            seq = sequence.incrementAndGet() & MAX_SEQUENCE;
        } while (seq >= MAX_SEQUENCE);

        // 组合各部分
        return formatTime(currentSecond)
             + formatNodeId()
             + formatRandom();
    }

    // 获取当前时间（秒级）
    private long getCurrentSecond() {
        return System.currentTimeMillis() / 1000;
    }

    // 格式化时间戳
    private String formatTime(long timestamp) {
        return LocalDateTime.ofEpochSecond(timestamp, 0, java.time.ZoneOffset.UTC)
               .format(TIME_FORMAT);
    }

    // 格式化节点ID（3位Base36）
    private String formatNodeId() {
        return Integer.toString(nodeId, 36)
               .toUpperCase()
               .replaceFirst("^0+(?!$)", "");
    }

    // 生成随机后缀（4位Hex）
    private String formatRandom() {
        return Integer.toHexString(
            ThreadLocalRandom.current().nextInt(65536)
        ).toUpperCase();
    }

    // 使用示例
//    public static void main(String[] args) {
//        OrderIdGenerator generator = new OrderIdGenerator(789); // 节点ID=789
//        for (int i = 0; i < 5; i++) {
//            System.out.println(generator.generate());
//        }
//    }
}